package com.google.code.rsser.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.code.rsser.dao.EntryDAO;
import com.google.code.rsser.dao.FeedDAO;
import com.google.code.rsser.dao.RemoteFeedDAO;
import com.google.code.rsser.dao.UserDAO;
import com.google.code.rsser.exception.InvalidFeedException;
import com.google.code.rsser.model.Entry;
import com.google.code.rsser.model.Feed;
import com.google.code.rsser.model.RemoteEntry;
import com.google.code.rsser.model.RemoteFeed;
import com.google.code.rsser.model.User;
import com.google.code.rsser.service.FeedService;

@Service("feedService")
@Transactional
public class FeedServiceImpl implements FeedService {

	private Logger logger = Logger.getLogger(FeedServiceImpl.class);
	
	@Autowired
	protected RemoteFeedDAO remoteFeedDAO;
	
	@Autowired
	protected FeedDAO feedDAO;
	
	@Autowired
	protected EntryDAO entryDAO;
	
	@Autowired
	protected UserDAO userDAO;
	
	public Feed subscribe(User user, String url) throws InvalidFeedException {
		Feed feed = feedDAO.getByUrl(url);
		
		if (feed == null) {
			RemoteFeed remoteFeed = remoteFeedDAO.fetch(url);
			feed = new Feed();
			
			feed.setDescription(remoteFeed.getDescription());
			feed.setLastUpdate(new Date());
			feed.setTitle(remoteFeed.getTitle());
			feed.setFeedUrl(url);
			feed.setUrl(remoteFeed.getUrl());
			feed.setSubscribedBy(new ArrayList<User>());
			
			if (logger.isDebugEnabled()) {
				logger.debug("Retrieved feed from [url=" + url + "] - [title=" + feed.getTitle() + "]");
			}
			
			for (RemoteEntry remoteEntry : remoteFeed.getEntries()) {
				Entry entry = convert(remoteEntry);
				
				entry.setFeed(feed);

				if (logger.isDebugEnabled()) {
					logger.debug("Retrieved entry from feed from [title=" + feed.getTitle() + "] - [title=" + remoteEntry.getTitle() + "], [url="
							+ remoteEntry.getUrl() + "]");
				}
				
				entryDAO.save(entry);
			}
		} else if (logger.isDebugEnabled()) {
			logger.debug("Retrieved feed from [url=" + url + "] - [title=" + feed.getTitle() + "]");
		}
		
		feed.getSubscribedBy().add(user);
		
		feedDAO.save(feed);
		
		return feed;
	}

	public boolean isFeedSubscribed(User user, String url) {
		Feed feed = feedDAO.getByUrl(url);
		
		return user.getFeedsSubscribed().contains(feed);
	}
	
	public List<Feed> findSubscribed(User user) {
		return user.getFeedsSubscribed();
	}

	public Feed get(Integer id) {
		return feedDAO.get(id);
	}

	public void updateAll() {
		// TODO
	}
	
	private Entry convert(RemoteEntry remoteEntry) {
		Entry entry = new Entry();
		
		entry.setDate(remoteEntry.getDate());
		entry.setDescription(remoteEntry.getDescription());
		entry.setTitle(remoteEntry.getTitle());
		entry.setUrl(remoteEntry.getUrl());
		
		return entry;
	}
}
